In [562]:
# -*- coding: utf-8 -*-
import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

def rgbImg(img):
    result = 0
    try:
        result = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    except:
        result = img
    return result

def grayImg(img):
    return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

def getImg(filename):
    #path = 'D:\\AOI\\OCR_data\\{}.jpg'.format(filename)
    #img = cv2.imread(path)
    img = cv2.imread(filename)
    if img == None:
        raise RuntimeError('Can not read img from the path.')
    return img

def normalize(img):
    img_back = img.copy()
    cv2.normalize(img, img_back, 0, 255, cv2.NORM_MINMAX)
    return img_back

def find_text_area(img):
    texts = []
    
    gray = grayImg(img)
    bl = cv2.medianBlur(gray, 3)
    ret, th = cv2.threshold(bl,20,255, cv2.THRESH_BINARY_INV)
    kernel = cv2.getStructuringElement(cv2.MORPH_ERODE,(3, 3))
    er1 = cv2.erode(th, kernel, 1)
    zero_cnts = cv2.findNonZero(er1)
    window = np.zeros(th.shape, dtype = np.uint8)
    cv2.drawContours(window, [zero_cnts], 0, (255,255,255), 1)
    er_kernel = cv2.getStructuringElement(cv2.MORPH_ERODE,(5, 7))
    er2 = cv2.erode(window, er_kernel, 1)
    di_kernel = cv2.getStructuringElement(cv2.MORPH_DILATE,(5, 7))
    di1 = cv2.dilate(er2, di_kernel, 1)
    image, cnts2, hierarchy= cv2.findContours(di1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    for i, c in enumerate(cnts2):
        min_rect = cv2.minAreaRect(c)
        box = np.int0(cv2.boxPoints(min_rect))
        rec_sum = box.sum(axis=1)
        point1 = box[np.argmin(rec_sum)]
        point2 = box[np.argmax(rec_sum)]        
        text_img = img[point1[1]+1:point2[1], point1[0]:point2[0]]
        texts.append(text_img)
    return texts

def seg_num(text, size):
    seg_list = []
    um = text[:,143:,:]
    num_right = text[:,106:143,:]
    dot = text[:,100:106,:]
    num_left = text[:,:100,:]
    
    seg_list.append(resize(um, size))
    #plt.imshow(rgbImg(um))
    #plt.show()

    right_length = 143-106
    for i in xrange(0, (143-106)/12):
        seg_img = num_right[:,right_length-12:right_length,:]
        seg_list.append(resize(seg_img, size))
        #plt.imshow(rgbImg(seg_img))
        #plt.show()
        right_length = right_length - 12    
    seg_list.append(resize(dot, size))
    #plt.imshow(rgbImg(dot))
    #plt.show()    

    left_length = 100
    for i in xrange(0, 100/12):
        seg_img = num_left[:,left_length-12:left_length,:]
        seg_list.append(resize(seg_img, size))
        #plt.imshow(rgbImg(seg_img))
        #plt.show()
        left_length = left_length - 12
    return seg_list

def resize(img, size):
    if not isinstance(img, np.ndarray):
        raise TypeError('Input image type is not numpy.ndarray.')
    elif not isinstance(size, tuple):
        raise TypeError('Input size type is not tuple.')
    elif len(size) > 2 or len(size)< 2:
        raise ValueError('Input size is invalid.')
    return cv2.resize(img, size, interpolation=cv2.INTER_LINEAR)
In [410]:
#辨識text區塊處理流程實驗區

# -*- coding: utf-8 -*-
img = getImg('0201-S2-維修-殘膠-座標'.decode('utf8').encode('big5'))
gray = grayImg(img)
print 'Gray-scale input:'
plt.imshow(gray,'gray')
plt.show()

gcopy = gray.copy()
bl = cv2.medianBlur(gcopy, 3)
print 'Median blur:'
plt.imshow(bl,'gray')
plt.show()

ret, th = cv2.threshold(bl,20,255, cv2.THRESH_BINARY_INV)
print 'Treshhold of binary inv:'
plt.imshow(th,'gray')
plt.show()

kernel = cv2.getStructuringElement(cv2.MORPH_ERODE,(3, 3))
er1 = cv2.erode(th, kernel, 1)
print 'Erode with 3*3 kernel'
plt.imshow(er1, 'gray')
plt.show()

zero_cnts = cv2.findNonZero(er1)
window = np.zeros(th.shape, dtype = np.uint8)
cv2.drawContours(window, [zero_cnts], 0, (255,255,255), 1)
print 'Find contours of non-zero area :'
plt.imshow(window, 'gray')
plt.show()

er_kernel = cv2.getStructuringElement(cv2.MORPH_ERODE,(5, 7))
er2 = cv2.erode(window, er_kernel, 1)
print 'Erode with 5*7 kernel:'
plt.imshow(er2, 'gray')
plt.show()

di_kernel = cv2.getStructuringElement(cv2.MORPH_DILATE,(5, 7))
di1 = cv2.dilate(er2, di_kernel, 1)
print 'Dilate with 5*7 kernel:'
plt.imshow(di1, 'gray')
plt.show()

copy = img.copy()
texts = []
image, cnts2, hierarchy= cv2.findContours(di1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(cnts2):
    min_rect = cv2.minAreaRect(c)
    box = np.int0(cv2.boxPoints(min_rect))
    rec_sum = box.sum(axis=1)
    point1 = box[np.argmin(rec_sum)]
    point2 = box[np.argmax(rec_sum)]
    rect_frame = cv2.rectangle(copy, tuple(point1), tuple(point2), (0,255,0), 1)
    
    window = np.zeros(img.shape, dtype = np.uint8)
    mask = cv2.rectangle(window, tuple(point1), tuple(point2), (255,255,255), -1)
    print 'Create the text-mask by contours:'
    plt.imshow(mask,'gray')
    plt.show()
    
    text = cv2.bitwise_and(img, mask)
    texts.append(text)
    print 'Find the intersection_{} of input and the mask_{}:'.format(i,i)
    plt.imshow(rgbImg(text))
    plt.show()
    
    text_img = img[point1[1]+1:point2[1], point1[0]:point2[0]]
    plt.imshow(rgbImg(text_img))
    plt.show()
    
print 'Find the texts:'
plt.imshow(rgbImg(copy))
plt.show()
Gray-scale input:
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:21: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
Median blur:
Treshhold of binary inv:
Erode with 3*3 kernel
Find contours of non-zero area :
Erode with 5*7 kernel:
Dilate with 5*7 kernel:
Create the text-mask by contours:
Find the intersection_0 of input and the mask_0:
Create the text-mask by contours:
Find the intersection_1 of input and the mask_1:
Create the text-mask by contours:
Find the intersection_2 of input and the mask_2:
Find the texts:
In [407]:
#切割數字實驗區

img = getImg('0064-S0-維修-殘膠-座標'.decode('utf8').encode('big5'))
plt.imshow(rgbImg(img))
plt.show()

texts = find_text_area(img)
text = texts[0]

#um固定從143開始, 故0~143的數值區塊大小恒定
#數字寬度固定為12, 小數點寬度6
#小數點位置固定在100~106
#小數點左側區塊以100倒數, 每隔12像素切割一個區塊, 最左側不足寬度12的區塊捨去

um = text[:,143:,:]
num_right = text[:,106:143,:]
dot = text[:,100:106,:]
num_left = text[:,:100,:]

plt.imshow(rgbImg(um))
plt.show()

right_length = 143-106
for i in xrange(0, (143-106)/12):
    plt.imshow(rgbImg(num_right[:,right_length-12:right_length,:]))
    plt.show()
    right_length = right_length - 12    

plt.imshow(rgbImg(dot))
plt.show()    

left_length = 100
for i in xrange(0, 100/12):
    plt.imshow(rgbImg(num_left[:,left_length-12:left_length,:]))
    plt.show()
    left_length = left_length - 12
    
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:21: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [408]:
# XYZ深黑色, 5位數+3位小數
img = getImg('0201-S2-維修-殘膠-座標'.decode('utf8').encode('big5'))
plt.imshow(rgbImg(img))
plt.show()

texts = find_text_area(img)

for text in texts:
    plt.imshow(rgbImg(text))
    plt.show()
    
for text in texts:
    seg_num(text)
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:21: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [409]:
# 無title + XYZ深黑色
img = getImg('0070-S0-維修-殘膠-座標'.decode('utf8').encode('big5'))
plt.imshow(rgbImg(img))
plt.show()

texts = find_text_area(img)

for text in texts:
    plt.imshow(rgbImg(text))
    plt.show()
    
for text in texts:
    seg_num(text)
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:21: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [382]:
img = getImg('0045-S2-維修-殘膠-座標'.decode('utf8').encode('big5'))
plt.imshow(rgbImg(img))
plt.show()

texts = find_text_area(img)

for text in texts:
    plt.imshow(rgbImg(text))
    plt.show()
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:21: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [383]:
# 無title, Z深黑色, Z非負數
img = getImg('0064-S0-維修-殘膠-座標'.decode('utf8').encode('big5'))
plt.imshow(rgbImg(img))
plt.show()

texts = find_text_area(img)
for text in texts:
    plt.imshow(rgbImg(text))
    plt.show()
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:21: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [405]:
img = getImg('0064-S0-維修-殘膠-座標'.decode('utf8').encode('big5'))
plt.imshow(rgbImg(img))
plt.show()

texts = find_text_area(img)
for text in texts:
    seg_num(text)
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:21: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [403]:
img = getImg('0045-S2-維修-殘膠-座標'.decode('utf8').encode('big5'))
plt.imshow(rgbImg(img))
plt.show()

texts = find_text_area(img)
for text in texts:
    seg_num(text)
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:21: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [568]:
# 遍歷資料圖片做切片
import os
loading_path = 'D:/AOI/OCR_data/'
saving_path = 'D:/AOI/OCR_segments/step0/'

count = 0
seg_list = []
for dirPath, dirNames, fileNames in os.walk(loading_path):
    for fname in fileNames:
        if count == 1:
            break
        else:
            count = count + 1
            src_path = os.path.join(dirPath, fname)
            img = getImg(src_path)
            #plt.imshow(img)
            #plt.show()
            
            texts = find_text_area(img)
            for i, text in enumerate(texts):
                seg_list  = seg_num(text,(20,20))
                for index, seg in enumerate(seg_list):
                    #path = saving_path + '{}_{}_{}.jpg'.format(fname[:-4], i, index)
                    #print path
                    #cv2.imwrite(path, seg)
                    plt.imshow(seg)
                    plt.show()
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:22: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [631]:
from numpy.linalg import norm

dic = {'11':'blank', '12':'dot', '13':'minus', '14':'um'}
prepare_list = ['0','1','2','3','4','5','6','7','8','9','11','12','13','14']
data_list = []
label_list = []

for label_name in prepare_list:
    path = 'D:/AOI/OCR_segments/step1/{}/'.format(label_name)
    print path

    for dirPath, dirNames, fileNames in os.walk(path):
        for fname in fileNames:
            src_path = os.path.join(dirPath, fname)
            seg_img = getImg(src_path)
            res_img = resize(seg_img,(20,20))

            gray = grayImg(res_img)
            #plt.imshow(gray,'gray')
            #plt.show()

            gx = cv2.Sobel(gray, cv2.CV_32F, 1, 0)
            gy = cv2.Sobel(gray, cv2.CV_32F, 0, 1)
            mag, ang = cv2.cartToPolar(gx, gy)
            bin_n = 16
            bin = np.int32(bin_n*ang/(2*np.pi))
            bin_cells = bin[:10,:10], bin[10:,:10], bin[:10,10:], bin[10:,10:]
            mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]
            hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
            hist = np.hstack(hists)

            eps = 1e-7
            hist /= hist.sum() + eps
            hist = np.sqrt(hist)
            hist /= norm(hist) + eps

            data_list.append(hist)
            label_list.append(label_name)
            
trainingDataMat = np.array(data_list, np.float32)
labelsMat = np.array(label_list, np.int32)
D:/AOI/OCR_segments/step1/0/
D:/AOI/OCR_segments/step1/1/
D:/AOI/OCR_segments/step1/2/
D:/AOI/OCR_segments/step1/3/
D:/AOI/OCR_segments/step1/4/
D:/AOI/OCR_segments/step1/5/
D:/AOI/OCR_segments/step1/6/
D:/AOI/OCR_segments/step1/7/
D:/AOI/OCR_segments/step1/8/
D:/AOI/OCR_segments/step1/9/
D:/AOI/OCR_segments/step1/11/
D:/AOI/OCR_segments/step1/12/
D:/AOI/OCR_segments/step1/13/
D:/AOI/OCR_segments/step1/14/
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:22: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [633]:
print len(label_list)
i = 97
print trainingDataMat[i], labelsMat[i]
590
[ 0.18478447  0.1540314   0.12624981  0.2589092   0.04490719  0.0296461
  0.02674264  0.03269264  0.02274132  0.          0.02747389  0.12627995
  0.17285323  0.09183018  0.14040294  0.35382417  0.16117172  0.13136892
  0.11135139  0.14348987  0.0288055   0.02084693  0.02054176  0.
  0.02199443  0.01444491  0.02642942  0.05573682  0.25802165  0.12438574
  0.06903348  0.09571627  0.01514957  0.          0.02525804  0.02421099
  0.17627077  0.09656274  0.12760803  0.34004855  0.29694408  0.04592694
  0.04995744  0.01544971  0.02560744  0.          0.0111736   0.
  0.00809779  0.0200867   0.02012989  0.01247087  0.13955569  0.12286513
  0.1264475   0.18505763  0.0442573   0.08360447  0.09371127  0.31320912
  0.06720025  0.02855848  0.02053311  0.02598595] 1
In [654]:
path = 'D:/AOI/OCR_segments/step2/test_data_01/'
count = 0
test_data = []
for dirPath, dirNames, fileNames in os.walk(path):
    for fname in fileNames:
        if count == -1:
            break
        else:
            src_path = os.path.join(dirPath, fname)
            print src_path.decode('big5')
            seg_img = getImg(src_path)
            res_img = resize(seg_img,(20,20))

            gray = grayImg(res_img)

            gx = cv2.Sobel(gray, cv2.CV_32F, 1, 0)
            gy = cv2.Sobel(gray, cv2.CV_32F, 0, 1)
            mag, ang = cv2.cartToPolar(gx, gy)
            bin_n = 16
            bin = np.int32(bin_n*ang/(2*np.pi))
            bin_cells = bin[:10,:10], bin[10:,:10], bin[:10,10:], bin[10:,10:]
            mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]
            hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
            hist = np.hstack(hists)

            eps = 1e-7
            hist /= hist.sum() + eps
            hist = np.sqrt(hist)
            hist /= norm(hist) + eps
            test_data.append(hist)
            count += 1
testDataMat = np.array(test_data, np.float32)
D:/AOI/OCR_segments/step2/test_data_01/0015-S2-維修-殘膠-座標_1_2.jpg
D:/AOI/OCR_segments/step2/test_data_01/0015-S2-維修-殘膠-座標_1_3.jpg
D:/AOI/OCR_segments/step2/test_data_01/0015-S2-維修-殘膠-座標_1_4.jpg
D:/AOI/OCR_segments/step2/test_data_01/0015-S2-維修-殘膠-座標_1_5.jpg
D:/AOI/OCR_segments/step2/test_data_01/0015-S2-維修-殘膠-座標_2_0.jpg
D:/AOI/OCR_segments/step2/test_data_01/0015-S2-維修-殘膠-座標_2_3.jpg
D:/AOI/OCR_segments/step2/test_data_01/0015-S2-維修-殘膠-座標_2_6.jpg
D:/AOI/OCR_segments/step2/test_data_01/0016-S2-不修-顆粒-座標_0_3.jpg
D:/AOI/OCR_segments/step2/test_data_01/0016-S2-不修-顆粒-座標_1_4.jpg
D:/AOI/OCR_segments/step2/test_data_01/0016-S2-不修-顆粒-座標_2_2.jpg
D:/AOI/OCR_segments/step2/test_data_01/0016-S2-不修-顆粒-座標_2_3.jpg
D:/AOI/OCR_segments/step2/test_data_01/0021-S2-維修-殘膠-座標_2_4.jpg
D:/AOI/OCR_segments/step2/test_data_01/0021-S2-維修-殘膠-座標_2_5.jpg
D:/AOI/OCR_segments/step2/test_data_01/0021-S2-維修-殘膠-座標_2_6.jpg
D:/AOI/OCR_segments/step2/test_data_01/0021-S2-維修-殘膠-座標_2_7.jpg
D:/AOI/OCR_segments/step2/test_data_01/0021-S2-維修-殘膠-座標_2_8.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_0_2.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_0_3.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_0_4.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_0_5.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_0_6.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_1_0.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_1_1.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_1_2.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_1_3.jpg
D:/AOI/OCR_segments/step2/test_data_01/0022-S2-不修-顆粒-座標_1_4.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_0_2.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_0_3.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_0_4.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_0_5.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_1_0.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_1_1.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_1_11.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_1_12.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_1_2.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_1_3.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_2_0.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_2_1.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_2_10.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_2_11.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_2_12.jpg
D:/AOI/OCR_segments/step2/test_data_01/0031-S2-維修-殘膠-座標_2_9.jpg
C:\Users\160619\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:22: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
In [626]:
test_data[0]
Out[626]:
array([ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.00391743,  0.00330451,  0.00243126,  0.00337747,
        0.00371999,  0.00318826,  0.00652025,  0.00970558,  0.01250811,
        0.00657597,  0.00298793,  0.00296134,  0.00369566,  0.00300609,
        0.0031954 ,  0.00269524,  0.00727675,  0.00512535,  0.00322926,
        0.00412243,  0.01195362,  0.00307483,  0.0056635 ,  0.00376501,
        0.00946161,  0.00790493,  0.01649858,  0.02779331,  0.04921637,
        0.01257709,  0.01189477,  0.00419653,  0.24882603,  0.15327659,
        0.15563157,  0.32612517,  0.42634386,  0.14991069,  0.16028128,
        0.23209799,  0.24403687,  0.16219281,  0.14775184,  0.3253348 ,
        0.42640875,  0.14663269,  0.15080134,  0.23644711])
In [655]:
svm = cv2.ml.SVM_create()
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
#svm.setTermCriteria((cv2.TERM_CRITERIA_COUNT, 100, 1.e-06))
svm.setC(1.0)
svm.train(trainingDataMat, cv2.ml.ROW_SAMPLE, labelsMat)

response = svm.predict(testDataMat)
In [656]:
for res in response[1]:
    result = None
    if dic.has_key(str(int(res[0]))):
        result  = dic[str(int(res[0]))]
    else:
        result = int(res[0])
    print result
9
3
dot
8
um
7
7
4
dot
0
2
dot
9
7
9
9
0
1
dot
7
2
um
9
9
6
dot
0
8
dot
5
um
0
blank
blank
0
5
um
0
blank
blank
blank
1
In [649]:
 
True
In [ ]: